package com.minimalist.lindi.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.Assert;
import com.minimalist.common.config.exception.BusinessException;
import com.minimalist.common.config.mybatis.bo.PageResp;
import com.minimalist.common.entity.basic.vo.file.FileVO;
import com.minimalist.common.entity.lindi.enums.LindiSubsidyApplicationFileTypeEnum;
import com.minimalist.common.entity.lindi.po.LindiSubsidyApplicationPayNotice;
import com.minimalist.common.entity.lindi.vo.subsidyapplicationfile.LindiSubsidyApplicationFileVO;
import com.minimalist.common.entity.lindi.vo.subsidyapplicationpaynotice.LindiSubsidyApplicationPayNoticeQueryVO;
import com.minimalist.common.entity.lindi.vo.subsidyapplicationpaynotice.LindiSubsidyApplicationPayNoticeVO;
import com.minimalist.common.entity.lindi.vo.subsidyapplicationpayrecord.LindiSubsidyApplicationPayRecordVO;
import com.minimalist.common.entity.lindi.vo.subsidyapplicationtownpayment.LindiSubsidyApplicationTownPaymentVO;
import com.minimalist.common.feign.client.basic.FileFeignClient;
import com.minimalist.common.response.R;
import com.minimalist.common.utils.UnqIdUtil;
import com.minimalist.lindi.manager.LindiSubsidyApplicationPayNoticeManager;
import com.minimalist.lindi.mapper.LindiSubsidyApplicationPayNoticeMapper;
import com.minimalist.lindi.service.LindiSubsidyApplicationPayNoticeService;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 林地指标交易平台_补贴申请支付通知 服务层实现。
 *
 * @author 11987
 * @since 2025-06-11
 */
@Service
public class LindiSubsidyApplicationPayNoticeServiceImpl extends ServiceImpl<
        LindiSubsidyApplicationPayNoticeMapper, LindiSubsidyApplicationPayNotice>
        implements LindiSubsidyApplicationPayNoticeService{

    @Autowired
    private LindiSubsidyApplicationPayNoticeMapper mapper;

    @Autowired
    private FileFeignClient fileFeignClient;

    @Autowired
    private LindiSubsidyApplicationPayNoticeManager lindiSubsidyApplicationPayNoticeManager;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addSubsidyApplicationPayNotice(
            LindiSubsidyApplicationPayNoticeVO subsidyApplicationPayNoticeVO){
        LindiSubsidyApplicationPayNotice notice = BeanUtil.copyProperties(
                subsidyApplicationPayNoticeVO
                , LindiSubsidyApplicationPayNotice.class);
        Long subsidyApplicationPayNoticeId = UnqIdUtil.uniqueId();
        notice.setSubsidyApplicationPayNoticeId(subsidyApplicationPayNoticeId);
        notice.setSubsidyApplicationId(subsidyApplicationPayNoticeVO.getSubsidyApplicationId());
        // 不再将文件添加到LindiSubsidyApplicationFile表，直接使用fileList字段存储文件ID
        int insert = mapper.insert(notice, true);
        Assert.isTrue(insert == 1, () -> new BusinessException(
                "添加补贴申请支付通知失败"));

        // 处理镇街支付明细
        if (subsidyApplicationPayNoticeVO.getTownPaymentList() != null && !subsidyApplicationPayNoticeVO.getTownPaymentList().isEmpty()){
            // 设置支付通知ID
            for (LindiSubsidyApplicationTownPaymentVO townPaymentVO
                    : subsidyApplicationPayNoticeVO.getTownPaymentList()){
                townPaymentVO.setSubsidyApplicationTownPaymentId(UnqIdUtil.uniqueId());
                townPaymentVO.setSubsidyApplicationPayNoticeId(subsidyApplicationPayNoticeId);
                townPaymentVO.setSubsidyApplicationId(
                        subsidyApplicationPayNoticeVO.getSubsidyApplicationId());
            }
            lindiSubsidyApplicationPayNoticeManager
                    .batchAddSubsidyApplicationTownPayment(
                            subsidyApplicationPayNoticeVO.getTownPaymentList());
        }
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSubsidyApplicationPayNoticeBySubsidyApplicationPayNoticeId(
            Long subsidyApplicationPayNoticeId){
        LindiSubsidyApplicationPayNotice notice = mapper
                .selectSubsidyApplicationPayNoticeBySubsidyApplicationPayNoticeId(
                        subsidyApplicationPayNoticeId);
        Assert.notNull(notice, () -> new BusinessException(
                "补贴申请支付通知不存在"));

        // 使用fileList字段删除文件
        if (notice.getFileList() != null && !notice.getFileList().trim().isEmpty()){
            String[] fileIdArray = notice.getFileList().split(",");
            List<Long> fileIds = new ArrayList<>();
            for (String fileIdStr : fileIdArray){
                try{
                    fileIds.add(Long.parseLong(fileIdStr.trim()));
                } catch (NumberFormatException e){
                    // 忽略无效的文件ID
                }
            }
            if (!fileIds.isEmpty()){
                try{
                    fileFeignClient.deleteBatchFiles(fileIds);
                } catch (Exception e){
                    // 记录日志但不影响主流程
                }
            }
        }

        // 删除镇街支付明细
        lindiSubsidyApplicationPayNoticeManager.deleteSubsidyApplicationTownPaymentBySubsidyApplicationPayNoticeId(subsidyApplicationPayNoticeId);
        int delete = mapper.deleteSubsidyApplicationPayNoticeBySubsidyApplicationPayNoticeId
                (subsidyApplicationPayNoticeId);
        Assert.isTrue(delete == 1, () -> new BusinessException(
                "删除补贴申请支付通知失败"));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSubsidyApplicationPayNoticeBySubsidyApplicationPayNoticeId(
            LindiSubsidyApplicationPayNoticeVO subsidyApplicationPayNoticeVO){
        LindiSubsidyApplicationPayNotice notice = mapper
                .selectSubsidyApplicationPayNoticeBySubsidyApplicationPayNoticeId(
                        subsidyApplicationPayNoticeVO.getSubsidyApplicationPayNoticeId());
        Assert.notNull(notice, () -> new BusinessException(
                "补贴申请支付通知不存在"));

        // 删除原有文件（使用fileList字段）
        if (notice.getFileList() != null && !notice.getFileList().trim().isEmpty()){
            String[] fileIdArray = notice.getFileList().split(",");
            List<Long> fileIds = new ArrayList<>();
            for (String fileIdStr : fileIdArray){
                try{
                    fileIds.add(Long.parseLong(fileIdStr.trim()));
                } catch (NumberFormatException e){
                    // 忽略无效的文件ID
                }
            }
            if (!fileIds.isEmpty()){
                try{
                    fileFeignClient.deleteBatchFiles(fileIds);
                } catch (Exception e){
                    // 记录日志但不影响主流程
                }
            }
        }

        // 不再将文件添加到LindiSubsidyApplicationFile表，直接使用fileList字段存储文件ID

        BeanUtil.copyProperties(subsidyApplicationPayNoticeVO, notice
                , CopyOptions.create().ignoreNullValue());
        int update = mapper.update(notice);
        Assert.isTrue(update == 1, () -> new BusinessException(
                "修改补贴申请支付通知失败"));

        // 处理镇街支付明细
        // 先删除原有的镇街支付明细
        lindiSubsidyApplicationPayNoticeManager
                .deleteSubsidyApplicationTownPaymentBySubsidyApplicationPayNoticeId(
                        subsidyApplicationPayNoticeVO.getSubsidyApplicationPayNoticeId());
        // 再添加新的镇街支付明细
        if (subsidyApplicationPayNoticeVO.getTownPaymentList() != null &&
                !subsidyApplicationPayNoticeVO.getTownPaymentList().isEmpty()){
            // 设置支付通知ID
            for (LindiSubsidyApplicationTownPaymentVO townPaymentVO :
                    subsidyApplicationPayNoticeVO.getTownPaymentList()){
                townPaymentVO.setSubsidyApplicationPayNoticeId(
                        subsidyApplicationPayNoticeVO.getSubsidyApplicationPayNoticeId());
                townPaymentVO.setSubsidyApplicationId(
                        subsidyApplicationPayNoticeVO.getSubsidyApplicationId());
            }
            subsidyApplicationPayNoticeVO.getTownPaymentList().forEach(item -> {
                item.setSubsidyApplicationPayNoticeId(subsidyApplicationPayNoticeVO.getSubsidyApplicationPayNoticeId());
                item.setSubsidyApplicationId(subsidyApplicationPayNoticeVO.getSubsidyApplicationId());
                item.setSubsidyApplicationTownPaymentId(UnqIdUtil.uniqueId());
            });
            lindiSubsidyApplicationPayNoticeManager.batchAddSubsidyApplicationTownPayment(subsidyApplicationPayNoticeVO.getTownPaymentList());
        }
    }

    @Override
    public PageResp<LindiSubsidyApplicationPayNoticeVO> getPageSubsidyApplicationPayNoticeList(
            LindiSubsidyApplicationPayNoticeQueryVO queryVO){
        // 分页查询
        Page<LindiSubsidyApplicationPayNotice> noticePage = mapper
                .selectPageSubsidyApplicationPayNoticeList(queryVO);
        // 数据转换
        List<LindiSubsidyApplicationPayNoticeVO> voList = BeanUtil.copyToList(
                noticePage.getRecords()
                , LindiSubsidyApplicationPayNoticeVO.class);
        return new PageResp<>(voList, noticePage.getTotalRow());
    }

    @Override
    public LindiSubsidyApplicationPayNoticeVO getSubsidyApplicationPayNoticeBySubsidyApplicationPayNoticeId(
            Long subsidyApplicationPayNoticeId){
        LindiSubsidyApplicationPayNotice notice = mapper
                .selectSubsidyApplicationPayNoticeBySubsidyApplicationPayNoticeId(
                        subsidyApplicationPayNoticeId);
        Assert.notNull(notice, () -> new BusinessException(
                "补贴申请支付通知不存在"));
        LindiSubsidyApplicationPayNoticeVO lindiSubsidyApplicationPayNoticeVO =
                BeanUtil.copyProperties(notice
                        , LindiSubsidyApplicationPayNoticeVO.class);

        // 使用fileList字段（逗号分隔的文件ID）获取文件信息
        if (lindiSubsidyApplicationPayNoticeVO.getFileList() != null && !lindiSubsidyApplicationPayNoticeVO.getFileList().trim().isEmpty()){
            String[] fileIdArray = lindiSubsidyApplicationPayNoticeVO.getFileList().split(",");
            List<Long> fileIds = new ArrayList<>();
            for (String fileIdStr : fileIdArray){
                try{
                    fileIds.add(Long.parseLong(fileIdStr.trim()));
                } catch (NumberFormatException e){
                    // 忽略无效的文件ID
                }
            }
            if (!fileIds.isEmpty()){
                R<List<FileVO>> filesResult = fileFeignClient.getFileListByFileIds(fileIds);
                if (filesResult.getCode() == cn.hutool.http.HttpStatus.HTTP_OK && filesResult.getData() != null){
                    List<FileVO> fileVOList = filesResult.getData();
                    // 转换为LindiSubsidyApplicationFileVO列表
                    List<LindiSubsidyApplicationFileVO> subsidyFileVOList = fileVOList.stream()
                            .map(fileVO -> {
                                LindiSubsidyApplicationFileVO subsidyFileVO = new LindiSubsidyApplicationFileVO();
                                subsidyFileVO.setSubsidyApplicationId(lindiSubsidyApplicationPayNoticeVO.getSubsidyApplicationId());
                                subsidyFileVO.setFileId(fileVO.getFileId());
                                subsidyFileVO.setFileType(LindiSubsidyApplicationFileTypeEnum.PAYMENT_NOTICE_FILE.getCode());
                                subsidyFileVO.setFile(fileVO);
                                return subsidyFileVO;
                            })
                            .collect(Collectors.toList());
                    lindiSubsidyApplicationPayNoticeVO.setFileVOList(subsidyFileVOList);
                }
            }
        }

        // 查询镇街支付明细列表
        List<LindiSubsidyApplicationTownPaymentVO> townPaymentList =
                lindiSubsidyApplicationPayNoticeManager
                        .getSubsidyApplicationTownPaymentListBySubsidyApplicationPayNoticeId(
                                subsidyApplicationPayNoticeId);
        lindiSubsidyApplicationPayNoticeVO.setTownPaymentList(townPaymentList);

        // 查询支付记录列表
        PageResp<LindiSubsidyApplicationPayRecordVO> payRecordPageResp =
                lindiSubsidyApplicationPayNoticeManager
                        .getSubsidyApplicationPayRecordPageBySubsidyApplicationId(
                                lindiSubsidyApplicationPayNoticeVO
                                        .getSubsidyApplicationId(), 1, 999);
        lindiSubsidyApplicationPayNoticeVO.setPayRecordList(payRecordPageResp.getRecords());

        return lindiSubsidyApplicationPayNoticeVO;
    }

    @Override
    public List<LindiSubsidyApplicationPayNoticeVO>
    getSubsidyApplicationPayNoticeListBySubsidyApplicationId(
            Long subsidyApplicationId){
        // 查询支付通知列表
        List<LindiSubsidyApplicationPayNotice> noticeList = mapper
                .selectPayNoticeListBySubsidyApplicationId(subsidyApplicationId);
        // 数据转换
        List<LindiSubsidyApplicationPayNoticeVO> voList = BeanUtil.copyToList(
                noticeList, LindiSubsidyApplicationPayNoticeVO.class);
        if (voList != null && !voList.isEmpty()){
            voList.forEach(item -> {
                // 使用fileList字段（逗号分隔的文件ID）获取文件信息
                if (item.getFileList() != null && !item.getFileList().trim().isEmpty()){
                    String[] fileIdArray = item.getFileList().split(",");
                    List<Long> fileIds = new ArrayList<>();
                    for (String fileIdStr : fileIdArray){
                        try{
                            fileIds.add(Long.parseLong(fileIdStr.trim()));
                        } catch (NumberFormatException e){
                            // 忽略无效的文件ID
                        }
                    }
                    if (!fileIds.isEmpty()){
                        R<List<FileVO>> filesResult = fileFeignClient
                                .getFileListByFileIds(fileIds);
                        if (filesResult.getCode() == cn.hutool.http.HttpStatus.HTTP_OK && filesResult.getData() != null){
                            List<FileVO> fileVOList = filesResult.getData();
                            // 转换为LindiSubsidyApplicationFileVO列表
                            List<LindiSubsidyApplicationFileVO> subsidyFileVOList = fileVOList.stream()
                                    .map(fileVO -> {
                                        LindiSubsidyApplicationFileVO subsidyFileVO = new LindiSubsidyApplicationFileVO();
                                        subsidyFileVO.setSubsidyApplicationId(item.getSubsidyApplicationId());
                                        subsidyFileVO.setFileId(fileVO.getFileId());
                                        subsidyFileVO.setFileType(LindiSubsidyApplicationFileTypeEnum.PAYMENT_NOTICE_FILE.getCode());
                                        subsidyFileVO.setFile(fileVO);
                                        return subsidyFileVO;
                                    })
                                    .collect(Collectors.toList());
                            item.setFileVOList(subsidyFileVOList);
                        }
                    }
                }
                // 查询镇街支付明细列表
                List<LindiSubsidyApplicationTownPaymentVO> townPaymentList =
                        lindiSubsidyApplicationPayNoticeManager
                                .getSubsidyApplicationTownPaymentListBySubsidyApplicationPayNoticeId(
                                        item.getSubsidyApplicationPayNoticeId());
                item.setTownPaymentList(townPaymentList);

                // 查询支付记录列表
                PageResp<LindiSubsidyApplicationPayRecordVO> payRecordPageResp =
                        lindiSubsidyApplicationPayNoticeManager
                                .getSubsidyApplicationPayRecordPageBySubsidyApplicationId(
                                        item.getSubsidyApplicationId(), 1, 999);
                List<LindiSubsidyApplicationPayRecordVO> records =
                        payRecordPageResp.getRecords();
                item.setPayRecordList(records);
            });
        }
        return voList != null ? voList : new ArrayList<>();
    }
}
